'use client';

import { useEffect } from 'react';

/**
 * 性能监控组件 - 收集和报告Web性能指标
 */
export function PerformanceMonitor() {
  useEffect(() => {
    // 等待页面完全加载后收集性能数据
    const collectPerformanceMetrics = () => {
      if (typeof window === 'undefined' || !window.performance) {
        return;
      }

      try {
        // 收集导航时间
        const navigation = performance.getEntriesByType(
          'navigation'
        )[0] as PerformanceNavigationTiming;

        if (navigation) {
          const metrics = {
            // 页面加载时间
            pageLoadTime: navigation.loadEventEnd - navigation.fetchStart,
            // DNS查询时间
            dnsTime: navigation.domainLookupEnd - navigation.domainLookupStart,
            // TCP连接时间
            tcpTime: navigation.connectEnd - navigation.connectStart,
            // 服务器响应时间
            serverResponseTime:
              navigation.responseEnd - navigation.requestStart,
            // DOM解析时间
            domParseTime:
              navigation.domContentLoadedEventEnd -
              navigation.domContentLoadedEventStart,
            // 资源加载时间
            resourceLoadTime:
              navigation.loadEventEnd - navigation.domContentLoadedEventEnd,
            // 首次内容绘制时间
            firstContentfulPaint: 0,
            // 最大内容绘制时间
            largestContentfulPaint: 0,
            // 累积布局偏移
            cumulativeLayoutShift: 0,
            // 首次输入延迟
            firstInputDelay: 0,
          };

          // 收集Paint Timing API数据
          const paintEntries = performance.getEntriesByType('paint');
          paintEntries.forEach(entry => {
            if (entry.name === 'first-contentful-paint') {
              metrics.firstContentfulPaint = entry.startTime;
            }
          });

          // 收集LCP数据
          if ('PerformanceObserver' in window) {
            try {
              const lcpObserver = new PerformanceObserver(list => {
                const entries = list.getEntries();
                const lastEntry = entries[
                  entries.length - 1
                ] as PerformanceEntry & { startTime: number };
                if (lastEntry) {
                  metrics.largestContentfulPaint = lastEntry.startTime;
                }
              });
              lcpObserver.observe({ entryTypes: ['largest-contentful-paint'] });

              // 收集CLS数据
              const clsObserver = new PerformanceObserver(list => {
                let clsValue = 0;
                for (const entry of list.getEntries()) {
                  const layoutShiftEntry = entry as PerformanceEntry & {
                    hadRecentInput?: boolean;
                    value: number;
                  };
                  if (!layoutShiftEntry.hadRecentInput) {
                    clsValue += layoutShiftEntry.value;
                  }
                }
                metrics.cumulativeLayoutShift = clsValue;
              });
              clsObserver.observe({ entryTypes: ['layout-shift'] });

              // 收集FID数据
              const fidObserver = new PerformanceObserver(list => {
                for (const entry of list.getEntries()) {
                  const fidEntry = entry as PerformanceEntry & {
                    processingStart: number;
                  };
                  metrics.firstInputDelay =
                    fidEntry.processingStart - entry.startTime;
                }
              });
              fidObserver.observe({ entryTypes: ['first-input'] });
            } catch (error) {
              console.warn('Performance Observer not supported:', error);
            }
          }

          // 发送性能数据到分析服务
          sendPerformanceData(metrics);
        }
      } catch (error) {
        console.warn('Failed to collect performance metrics:', error);
      }
    };

    // 页面加载完成后收集数据
    if (document.readyState === 'complete') {
      setTimeout(collectPerformanceMetrics, 1000);
    } else {
      window.addEventListener('load', () => {
        setTimeout(collectPerformanceMetrics, 1000);
      });
    }

    // 收集资源加载性能
    const collectResourceMetrics = () => {
      const resources = performance.getEntriesByType('resource');
      const slowResources = resources.filter(resource => {
        return resource.duration > 1000; // 超过1秒的资源
      });

      if (slowResources.length > 0) {
        sendResourceData(slowResources as PerformanceResourceTiming[]);
      }
    };

    setTimeout(collectResourceMetrics, 5000);
  }, []);

  return null;
}

/**
 * 性能指标接口
 */
interface PerformanceMetrics {
  pageLoadTime: number;
  dnsTime: number;
  tcpTime: number;
  serverResponseTime: number;
  domParseTime: number;
  resourceLoadTime: number;
  firstContentfulPaint: number;
  largestContentfulPaint: number;
  cumulativeLayoutShift: number;
  firstInputDelay: number;
}

/**
 * 发送性能数据到分析服务
 */
function sendPerformanceData(metrics: PerformanceMetrics) {
  if (process.env.NODE_ENV === 'development') {
    console.log('Performance Metrics:', metrics);
    return;
  }

  // 在生产环境中发送到分析服务
  try {
    // 使用navigator.sendBeacon确保数据发送
    if (navigator.sendBeacon) {
      const data = JSON.stringify({
        type: 'performance',
        url: window.location.href,
        userAgent: navigator.userAgent,
        timestamp: Date.now(),
        metrics,
      });

      navigator.sendBeacon('/api/analytics/performance', data);
    } else {
      // 降级到fetch
      fetch('/api/analytics/performance', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          type: 'performance',
          url: window.location.href,
          userAgent: navigator.userAgent,
          timestamp: Date.now(),
          metrics,
        }),
        keepalive: true,
      }).catch(console.warn);
    }
  } catch (error) {
    console.warn('Failed to send performance data:', error);
  }
}

/**
 * 发送资源加载数据
 */
function sendResourceData(resources: PerformanceEntry[]) {
  if (process.env.NODE_ENV === 'development') {
    console.log('Slow Resources:', resources);
    return;
  }

  try {
    const data = JSON.stringify({
      type: 'resources',
      url: window.location.href,
      timestamp: Date.now(),
      resources: resources.map(resource => {
        const resourceTiming = resource as PerformanceResourceTiming;
        return {
          name: resource.name,
          duration: resource.duration,
          size: resourceTiming.transferSize || 0,
        };
      }),
    });

    if (navigator.sendBeacon) {
      navigator.sendBeacon('/api/analytics/resources', data);
    }
  } catch (error) {
    console.warn('Failed to send resource data:', error);
  }
}

/**
 * 错误监控组件
 */
export function ErrorMonitor() {
  useEffect(() => {
    // 监听JavaScript错误
    const handleError = (event: ErrorEvent) => {
      const errorData = {
        type: 'javascript-error',
        message: event.message,
        filename: event.filename,
        lineno: event.lineno,
        colno: event.colno,
        stack: event.error?.stack,
        url: window.location.href,
        userAgent: navigator.userAgent,
        timestamp: Date.now(),
      };

      sendErrorData(errorData);
    };

    // 监听Promise rejection
    const handleUnhandledRejection = (event: PromiseRejectionEvent) => {
      const errorData = {
        type: 'unhandled-promise-rejection',
        reason: event.reason?.toString() || 'Unknown promise rejection',
        stack: event.reason?.stack,
        url: window.location.href,
        userAgent: navigator.userAgent,
        timestamp: Date.now(),
      };

      sendErrorData(errorData);
    };

    window.addEventListener('error', handleError);
    window.addEventListener('unhandledrejection', handleUnhandledRejection);

    return () => {
      window.removeEventListener('error', handleError);
      window.removeEventListener(
        'unhandledrejection',
        handleUnhandledRejection
      );
    };
  }, []);

  return null;
}

/**
 * 错误数据接口
 */
interface ErrorData {
  type: string;
  message?: string;
  filename?: string;
  lineno?: number;
  colno?: number;
  stack?: string;
  reason?: string;
  url: string;
  userAgent: string;
  timestamp: number;
}

/**
 * 发送错误数据
 */
function sendErrorData(errorData: ErrorData) {
  if (process.env.NODE_ENV === 'development') {
    console.error('Error captured:', errorData);
    return;
  }

  try {
    const data = JSON.stringify(errorData);

    if (navigator.sendBeacon) {
      navigator.sendBeacon('/api/analytics/errors', data);
    } else {
      fetch('/api/analytics/errors', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: data,
        keepalive: true,
      }).catch(console.warn);
    }
  } catch (error) {
    console.warn('Failed to send error data:', error);
  }
}

/**
 * 用户行为分析组件
 */
export function UserAnalytics() {
  useEffect(() => {
    // 页面访问统计
    const trackPageView = () => {
      const pageData = {
        type: 'page-view',
        url: window.location.href,
        title: document.title,
        referrer: document.referrer,
        userAgent: navigator.userAgent,
        timestamp: Date.now(),
        viewport: {
          width: window.innerWidth,
          height: window.innerHeight,
        },
      };

      sendAnalyticsData(pageData);
    };

    trackPageView();

    // 监听页面可见性变化
    const handleVisibilityChange = () => {
      if (document.visibilityState === 'hidden') {
        const sessionData = {
          type: 'session-end',
          url: window.location.href,
          duration:
            Date.now() -
            (window as unknown as Window & { sessionStartTime: number })
              .sessionStartTime,
          timestamp: Date.now(),
          userAgent: navigator.userAgent,
        };

        sendAnalyticsData(sessionData);
      }
    };

    // 记录会话开始时间
    (
      window as unknown as Window & { sessionStartTime: number }
    ).sessionStartTime = Date.now();

    document.addEventListener('visibilitychange', handleVisibilityChange);

    return () => {
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    };
  }, []);

  return null;
}

/**
 * 分析数据接口
 */
interface AnalyticsData {
  type: string;
  url: string;
  title?: string;
  referrer?: string;
  userAgent: string;
  timestamp: number;
  viewport?: {
    width: number;
    height: number;
  };
  duration?: number;
}

/**
 * 发送分析数据
 */
function sendAnalyticsData(data: AnalyticsData) {
  if (process.env.NODE_ENV === 'development') {
    console.log('Analytics:', data);
    return;
  }

  try {
    const payload = JSON.stringify(data);

    if (navigator.sendBeacon) {
      navigator.sendBeacon('/api/analytics/events', payload);
    }
  } catch (error) {
    console.warn('Failed to send analytics data:', error);
  }
}

export default PerformanceMonitor;
